package com.zscat.mallplus.qsg.impl;

import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.List;
import java.util.UUID;

@Service
@Slf4j
public class MqttConfigService {

    //mqtt连接
    private MqttClient mqttClient;
    //MQTT服务器用户名
    @Value("${mqtt.userName}")
    private String userName;
    //MQTT服务器密码
    @Value("${mqtt.passWord}")
    private String passWord;
    //MQTT服务器的IP地址和端口
    @Value("${mqtt.host}")
    private String host;
    //所要订阅的Topic列表,topic列表通过逗号进行分割
    @Value("${mqtt.topics}")
    private List<String> sub_Topic;
    private String clientId = createUUID();

    /**
     * 配置MQTT连接信息
     * @return
     */
    public MqttConnectOptions getOptions(){
        MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
        //是否清除Session
        mqttConnectOptions.setCleanSession(false);
        //MQTT服务器用户名
        mqttConnectOptions.setUserName(userName);
        //MQTT服务器密码
        mqttConnectOptions.setPassword(passWord.toCharArray());
        //MQTT连接超时时间,10s
        mqttConnectOptions.setConnectionTimeout(10);
        //设置MQTT心跳时间,20s
        mqttConnectOptions.setKeepAliveInterval(20);
        return mqttConnectOptions;
    }

    /**
     * 连接MQTT服务端
     */
    public void connect(){
        //防止重复创建MQTTClient实例
        if (mqttClient == null){
            try {
                mqttClient = new MqttClient(host,clientId,new MemoryPersistence());
                //MqttMessageCallback是接收订阅topic数据推送的回调
                mqttClient.setCallback(new MqttMessageCallback());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        MqttConnectOptions options = getOptions();
        //判断拦截状态
        if (!mqttClient.isConnected()){
            try {
                mqttClient.connect(options);
                log.info("[MQTT] 连接成功！");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }else {
            try {
                mqttClient.disconnect();
                mqttClient.connect(options);
                log.info("[MQTT] 连接成功！");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 启动程序并订阅Topic
     * @PostConstruct 注解的作用是服务初始化启动完成后会主动执行有该注解的方法
     */
    @PostConstruct
    public void start(){
        log.info("MQTT连接数据初始化成功，开始连接....");
        try {
            connect();
//            for (int i = 0;i<sub_Topic.size();i++){
//                mqttClient.subscribe(sub_Topic.get(i),1);
//            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 发送数据
     */
    public void publish(String topic, String content) throws MqttException {
        MqttMessage message = new MqttMessage(content.getBytes());
        try{
//            mqttClient.subscribe(topic,1);
            mqttClient.publish(topic, message);
        }catch (Exception e){
            e.printStackTrace();
        }
    }


    /**
     * 订阅主题
     */
    public void subscribe(String topic, int qos) throws MqttException {
        try{
            mqttClient.subscribe(topic,qos);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     *断线重连
     */
    public void reConnect() throws MqttException {
        if (null != mqttClient){
            MqttConnectOptions options = getOptions();
            mqttClient.connect(options);
            log.info("[MQTT] 重连成功！");
        }
    }


    public static String createUUID(){
        UUID uuid = UUID.randomUUID();
        String uuidStr = String.valueOf(uuid);
        String uuidStr2 = uuidStr.replaceAll("-","");
        return uuidStr2;
    }
}
